package cn.edu.lingnan.fruitshop.service.impl;

import cn.edu.lingnan.fruitshop.common.Email;
import cn.edu.lingnan.fruitshop.common.JSONResult;
import cn.edu.lingnan.fruitshop.pojo.User;
import cn.edu.lingnan.fruitshop.mapper.UserMapper;
import cn.edu.lingnan.fruitshop.service.UserService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import javax.servlet.http.HttpSession;
import java.util.Date;
import java.util.UUID;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 张小凡
 * @since 2022-01-04
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    // 注入mapper层对象
    @Autowired(required = false)
    private UserMapper userMapper;

    // 验证邮箱是否唯一 以及格式
    @Override
    public JSONResult<Void> checkEmail(String email) {

        //判断参数------->判断邮箱是否为空
        if ("".equals(email) || email == null)
            return new JSONResult<>(202, "邮箱不能为空");

        //判断邮箱格式是否正确
        String regx = "[1-9]\\d{7,10}@qq\\.com";
        if (!email.matches(regx))
            return new JSONResult<>(203, "邮箱格式错误");

        // 判断邮箱是否唯一
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_email", email);
        User user = userMapper.selectOne(queryWrapper);
        if (user == null)
            return new JSONResult<>(200, "邮箱验证通过");
        else
            return new JSONResult<>(201, "该邮箱已被注册");
    }

    // 发送邮箱验证码
    @Override
    public JSONResult<Void> sendEmailCode(String email, HttpSession session) {

        // 判断参数email 是否为空
        if ("".equals(email))
            return new JSONResult<>(201, "邮箱不能为空");

        // 验证邮箱格式是否正确
        JSONResult<Void> voidJSONResult = checkEmail(email);
        if (voidJSONResult.getCode() != 200)
            return new JSONResult<>(203,"邮箱格式不正确");

        // 调用方法发送邮件
        String code = Email.sendEmail(email);

        //邮件发送失败，无法获取验证码
        if (code == null)
            return new JSONResult<>(202, "验证码获取失败，请稍后重试");

        session.setAttribute("code", code);
        return new JSONResult<>(200, "发送成功");
    }

    // 进行注册
    @Override
    public JSONResult<Void> doReg(String email, String password, String comfirmPwd, String code, String option, HttpSession session) {

        // 验证邮箱
        JSONResult<Void> result = checkEmail(email);
        if (result.getCode() != 200) return result;

        //验证密码
        JSONResult<Void> result1 = checkPasswordAndComfirmPwd(password, comfirmPwd);
        if (result1.getCode() != 200) return result1;

        // 全局验证码是否为空
        if ("".equals(code) || code == null)
            return new JSONResult<>(201,"验证码不能为空");

        // 看是否超时
        String realCode = (String) session.getAttribute("code");
        if ("".equals(realCode) || realCode== null)
            return new JSONResult<>(203,"会话超时，请重新发送");

        // 验证验证码是否正确
        if (!code.equals(realCode))
            return new JSONResult<>(202,"验证码错误");

        //生成盐 默认生成一个36位的数字
        String salt = UUID.randomUUID().toString();
        String md5Password = m5dPassword(password,salt);


        // 将对象封装到数据中
        User user = new User().setUserEmail(email).setCreateTime(new Date())
                .setPassword(md5Password).setSalt(salt).setIsDelete(1);

        // 判断身份 0为商家 就是 seller 2 为普通用户就是 buyer
        if (option.equals("seller")) user.setFlag(0);
        else user.setFlag(1);

        // 插入数据，进行数据库操作
        int row = userMapper.insert(user);
        if (row!=1){
            return new JSONResult<>(204,"用户注册失败");
        }
        return new JSONResult<>(200,"用户注册成功");
    }




    //封装方用于密码加密
    private String m5dPassword(String password,String salt){
        String md5Pwd = password+salt;
        for (int i = 0; i < 10; i++) {
            String s = DigestUtils.md5DigestAsHex(md5Pwd.getBytes());
        }
        return md5Pwd;
    }

    // 验证密码
    @Override
    public JSONResult<Void> checkPasswordAndComfirmPwd(String password, String comfirmPwd) {
        //密码是否为空
        if ("".equals(password) || password == null)
            return new JSONResult<>(201,"密码不能为空");
        //验证密码是否为空
        if ("".equals(comfirmPwd) || comfirmPwd == null)
            return new JSONResult<>(202,"确认密码不能为空");
        // 两次密码是否一致
        if (!comfirmPwd.equals(password))
            return new JSONResult<>(203,"两次密码不一致");
        // 符合条件
        return new JSONResult<>(200,"密码符合条件");
    }


    // 登录时检验邮箱是否存在
    @Override
    public JSONResult<Void> checkLoginEmail(String email) {
        // 判断字段是否为空
        if ("".equals(email) || email == null)
            return new JSONResult<>(201,"邮箱不能为空");

        //格式验证
        String regx = "[1-9]\\d{7,10}@qq\\.com";
        if (!email.matches(regx)) return new JSONResult<>(202,"邮箱格式错误");

        // 验证邮箱是否存在
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_email",email);
        User user = userMapper.selectOne(queryWrapper);
        if (user == null){
            return new JSONResult<>(203,"该邮箱不存在，请重新输入");
        }
        return new JSONResult<>(200,"√");
    }

    // 用户进行登录操作
    @Override
    public JSONResult<Void> doLogin(String email, String password, String code,HttpSession session) {

        //验证邮箱是否合格
        JSONResult<Void> result = checkLoginEmail(email);
        if (result.getCode() != 200) return result;

        // 密码是否为空
        if ("".equals(password) || password == null)
            return new JSONResult<>(201,"密码不能为空");

        // 从邮箱中取出相应的salt
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_email", email);
        User user = userMapper.selectOne(queryWrapper);

        // 用户可能不存在
        if (user == null)
            return new JSONResult<>(206,"该数据可能被删除");

        String realPassword = user.getPassword();
        String salt = user.getSalt();

        //验证密码
        String m5dPassword = m5dPassword(password,salt);
        if (!(m5dPassword.equals(realPassword)))
            return new JSONResult<>(202,"密码不正确");

        // code是否为空
        if ("".equals(code) || code == null)
            return new JSONResult<>(204,"验证码不能为空");

        // 从全局会话里面拿出正确的验证码
        String loginCode = (String) session.getAttribute("loginCode");
        System.out.println(loginCode);

        // 全局验证码是否为空
        if ("".equals(loginCode) || loginCode == null)
            return new JSONResult<>(203,"会话超时，请再次点击验证码");

        //验证码是否一致
        if(!(loginCode.equals(code.toUpperCase())))
            return new JSONResult<>(205,"验证码不正确，请重新输入");

        // 为了后面跳转页面可以获得数据，在这里绑定用户
        session.setAttribute("user",user);
        if(user.getFlag()==0)
        {
            return new JSONResult<>(222,"登录成功");
        }

        return new JSONResult<>(200,"登录成功");
    }

    // 用户进行密码重置操作
    @Override
    public JSONResult<Void> doResetPwd(String email,String password,String comfirmPwd,String code,HttpSession session) {
        // 验证邮箱
        JSONResult<Void> result = checkEmail(email);
        if (result.getCode() == 202 || result.getCode() == 203 ) return result;
        if (result.getCode() == 200) return new JSONResult<>(206,"该邮箱不存在");

        //验证密码
        JSONResult<Void> result1 = checkPasswordAndComfirmPwd(password, comfirmPwd);
        if (result1.getCode() != 200) return result1;

        // 全局验证码是否为空
        if ("".equals(code) || code == null)
            return new JSONResult<>(201,"验证码不能为空");

        // 看是否超时
        String realCode = (String) session.getAttribute("code");
        if ("".equals(realCode) || realCode== null)
            return new JSONResult<>(203,"会话超时，请重新发送");

        // 验证验证码是否正确
        if (!code.equals(realCode))
            return new JSONResult<>(202,"验证码错误");

        //生成盐 默认生成一个36位的数字
        String salt = UUID.randomUUID().toString();
        String md5Password = m5dPassword(password,salt);

        // 根据email找到用户
        User user1 = userMapper.selectOne(new QueryWrapper<User>().eq("user_email", email));
        if (user1 == null) return new JSONResult<>(205,"该用户已被删除");

        // 更改其密码
        user1.setPassword(md5Password).setModifyTime(new Date()).setSalt(salt);

        // 进行数据操作
        int i = userMapper.updateById(user1);

        if (i != 1){
            return new JSONResult<>(204,"重置密码失败");
        }

        return new JSONResult<>(200,"重置密码成功");


    }

    // 重置密码时发送邮箱验证码
    @Override
    public JSONResult<Void> resetPwdSendEmailCode(String email,HttpSession session) {

        // 检验邮箱
        JSONResult<Void> result = checkEmail(email);
        if (result.getCode() == 202 || result.getCode() == 203)
            return result;
        if (result.getCode() == 200 )
            return new JSONResult<>(204,"改邮箱不存在");


        // 调用方法发送邮件
        String code = Email.sendEmail(email);

        //邮件发送失败，无法获取验证码
        if (code == null)
            return new JSONResult<>(202, "验证码获取失败，请稍后重试");

        session.setAttribute("code", code);
        return new JSONResult<>(200, "发送成功");
    }


}
